﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Web;
using System.Web.Mvc;
using System.Web.Script.Serialization;
using ABC.Business.Models;
using ABC.Controllers.ViewModels.My;
using ABC.Controllers.ViewModels.My.News;
using ABC.Core.Extentions;
using System.Linq;
using ABC.Domain.Entities;
using ABC.Domain.Json;
using RosService.Data;

namespace ABC.Controllers.Areas.My
{
    [Authorize]
    public class ClientsController : BaseController
    {
        private readonly ClientsModel clientsModel;
        private readonly RosModel rosModel;
        private readonly UserModel userModel;
        private readonly RbsCalcModel rbsCalcModel;
        private readonly PartnerModel partnerModel;
        private const int pageSize = 5;
        public ClientsController(ClientsModel clientsModel, UserModel userModel, RosModel rosModel, RbsCalcModel rbsCalcModel, PartnerModel partnerModel)
        {
            this.partnerModel = partnerModel;
            this.clientsModel = clientsModel;
            this.userModel = userModel;
            this.rosModel = rosModel;
            this.rbsCalcModel = rbsCalcModel;
        }
        public ActionResult Index(int? page, string query, string status, string pagesize)
        {
            var model = new MyClientsViewModel();
            if (!page.HasValue)
            {
                page = 1;
            }
            if (string.IsNullOrEmpty(pagesize))
            {
                pagesize = model.ListForPageSize.First().Value;
            }
            if (string.IsNullOrEmpty(status))
            {
                status = "atwork";
            }
            var clientsId = new string[] { };
            switch (status)
            {
                case "atwork":
                    var deletedClientsId = rosModel.GetEntityValue<string>(CurrentUser.Id, "СписокУдаленныхКлиентов").Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                    var clientsAllId = rosModel.GetEntityValue<string>(CurrentUser.Id, "СписокКлиентов");
                    foreach (var id in deletedClientsId)
                    {
                        if (clientsAllId.IndexOf(id) >= 0)
                        {
                            clientsAllId = clientsAllId.Replace(string.Format("{0},", id), "");
                        }
                    }
                    clientsId = clientsAllId.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                    break;
                case "delete":
                    clientsId = rosModel.GetEntityValue<string>(CurrentUser.Id, "СписокУдаленныхКлиентов").Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                    break;
            }
            if (string.IsNullOrEmpty(query))
            {
                model.PageCount = (int)Math.Ceiling((double)clientsId.Length / Int32.Parse(pagesize));
                clientsId = clientsId.Skip((page.Value - 1) * Int32.Parse(pagesize)).Take(Int32.Parse(pagesize)).ToArray();
                model.Clients = clientsModel.GetClients(clientsId, CurrentUser.Id, loadSimpleClient: true); //end,, 
                model.PageNumber = page.Value;
                return View(model);
            }
            var searchClients = clientsModel.GetClients(clientsId, CurrentUser.Id, query, true);
            model.PageCount = (int)Math.Ceiling((double)searchClients.Count / Int32.Parse(pagesize));
            model.Clients = searchClients.Skip((page.Value - 1) * Int32.Parse(pagesize)).Take(Int32.Parse(pagesize)).ToList();
            model.PageNumber = page.Value;
            return View(model);
        }
        public ActionResult Objects(int? page, string query, string status, string pagesize)
        {
            var model = new MyObjectsViewModel();
            if (!page.HasValue)
            {
                page = 1;
            }
            if (string.IsNullOrEmpty(pagesize) || pagesize == "0")
            {
                pagesize = model.ListForPageSize.First().Value;
            }
            if (string.IsNullOrEmpty(status))
            {
                status = "atwork";
            }
            model.Objects = clientsModel.GetObjects(CurrentUser.Id, status, query);
            model.PageCount = (int)Math.Ceiling((double)model.Objects.Count / Int32.Parse(pagesize));
            model.Objects = model.Objects.Skip((page.Value - 1) * Int32.Parse(pagesize)).Take(Int32.Parse(pagesize)).ToList();
            model.PageNumber = page.Value;
            return View(model);
        }

        [HttpGet]
        public ActionResult Add(string id)
        {
            var model = new MyNewClientViewModel();
            if (!string.IsNullOrEmpty(id))
            {
                var client = clientsModel.GetClient(id, CurrentUser.Id);
                model.FirstName = client.FirstName;
                model.LastName = client.LastName;
                model.MiddleName = client.MiddleName;
                model.Avatar = client.Avatar;
                model.Sex = client.Sex;
                model.BirthDay = client.BirthDay == DateTime.MinValue ? "" : client.BirthDay.ToString("dd.MM.yyyy");
                model.DateLawToCar = client.DateLawToCar.ToString("dd.MM.yyyy");
                model.Company = client.Company;
                model.Department = client.Department;
                model.Post = client.Post;
                model.Notes = client.Notes;
                //Для получения данных клиента используются методы, что и для получения данных пользователя
                model.ListPhones = userModel.GetUserPhones(id);
                model.ListEmails = userModel.GetUserEmails(id);
                model.ListIm = userModel.GetUserIms(id);
                model.ListSocNetworks = userModel.GetUserSocNetworks(id);
                model.ListAddresses = userModel.GetClientAddresses(id);
                model.NewClientId = id;
                return View(model);
            }
            model.ListPhones.Add(new FieldWithDrop(userModel.GetListFor("phone"), "PhoneValue0", ""));
            model.ListEmails.Add(new FieldWithDrop(userModel.GetListFor("email"), "EmailValue0", ""));
            model.ListIm.Add(new FieldWithDrop(userModel.GetListFor("im"), "ImValue0", ""));
            model.ListSocNetworks.Add(new FieldWithDrop(userModel.GetListFor("socnet"), "SocNetValue0", ""));
            model.ListAddresses.Add(new FieldWithDrop(userModel.GetListFor("address"), "AddressValue0", ""));

            return View(model);
        }

        [HttpPost]
        public ActionResult Add(MyNewClientViewModel model)
        {
            if (!ModelState.IsValidField("EmailValue0") || !ModelState.IsValidField("FirstName") || !Boolean.Parse(Request.Form.Get("isExperience")))
            {
                model.ErrorName = !ModelState.IsValidField("FirstName");
                model.WarningEmail = !ModelState.IsValidField("EmailValue0");
                return View(model);
            }
            var typesPhone = Request.Form["PhoneType"].Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            var typesEmail = Request.Form["EmailType"].Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            var typesIm = Request.Form["ImType"].Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            var typesAddress = Request.Form["AddressType"].Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            var typesSocNet = Request.Form["SocNetType"].Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            var fields = new Dictionary<string, object>();

            var countField = 0;
            for (var i = 0; i < typesEmail.Length; i++)
            {
                if (!string.IsNullOrEmpty(Request.Form["EmailValue" + i]))
                {
                    fields.Add("Email" + (countField == 0 ? "" : countField.ToString()), Request.Form["EmailValue" + i]);
                    fields.Add("ТипEmail" + (countField == 0 ? "" : countField.ToString()), typesEmail[i]);
                    countField++;
                }
            }
            for (var i = countField; i < typesEmail.Length; i++)
            {
                fields.Add("Email" + i, "");
            }
            countField = 0;
            for (var i = 0; i < typesPhone.Length; i++)
            {
                if (!string.IsNullOrEmpty(Request.Form["PhoneValue" + i]))
                {
                    fields.Add("ТелефонныйНомер" + (countField == 0 ? "" : countField.ToString()), Request.Form["PhoneValue" + i]);
                    fields.Add("ТипТелефонныйНомер" + (countField == 0 ? "" : countField.ToString()), typesPhone[i]);
                    countField++;
                }
            }
            for (var i = countField; i < typesPhone.Length; i++)
            {
                fields.Add("ТелефонныйНомер" + i, "");
            }
            countField = 0;
            for (var i = 0; i < typesIm.Length; i++)
            {
                if (!string.IsNullOrEmpty(Request.Form["ImValue" + i]))
                {
                    fields.Add("Im" + countField, Request.Form["ImValue" + i]);
                    fields.Add("ТипIm" + countField, typesIm[i]);
                    countField++;
                }
            }
            for (var i = countField; i < typesIm.Length; i++)
            {
                fields.Add("Im" + i, "");
            }
            countField = 0;
            for (var i = 0; i < typesAddress.Length; i++)
            {
                if (!string.IsNullOrEmpty(Request.Form["AddressValue" + i]))
                {
                    fields.Add("Адрес" + countField, Request.Form["AddressValue" + i]);
                    fields.Add("ТипАдрес" + countField, typesAddress[i]);
                    countField++;
                }
            }
            for (var i = countField; i < typesAddress.Length; i++)
            {
                fields.Add("Адрес" + i, "");
            }
            countField = 0;
            for (var i = 0; i < typesSocNet.Length; i++)
            {
                if (!string.IsNullOrEmpty(Request.Form["SocNetValue" + i]))
                {
                    fields.Add("СоцСеть" + countField, Request.Form["SocNetValue" + i]);
                    fields.Add("ТипСоцСеть" + countField, typesSocNet[i]);
                    countField++;
                }
            }
            for (var i = countField; i < typesSocNet.Length; i++)
            {
                fields.Add("СоцСеть" + i, "");
            }
            fields.Add("Имя", model.FirstName);
            fields.Add("Фамилия", model.LastName);
            fields.Add("Пол", model.Sex);
            fields.Add("Отчество", model.MiddleName);
            fields.Add("Компания", model.Company);
            fields.Add("Должность", model.Post);
            fields.Add("Отдел", model.Department);
            fields.Add("НазваниеОбъекта", string.Format("{0} {1}", model.FirstName, model.LastName));
            fields.Add("Удален", false);
            DateTime date;
            fields.Add("ДатаРождения", DateTime.TryParse(model.BirthDay, CultureInfo.CreateSpecificCulture("ru-RU"), DateTimeStyles.None, out date) ? date : DateTime.MinValue);
            DateTime dateDrive;
            fields.Add("ДатаПолученияПрав", DateTime.TryParse(model.DateLawToCar, CultureInfo.CreateSpecificCulture("ru-RU"), DateTimeStyles.None, out dateDrive) ? dateDrive : DateTime.MinValue);
            fields.Add("Заметки", model.Notes);

            fields.Add("Возраст", string.IsNullOrEmpty(Request.Form["age-digit"]) ? 0 : Int32.Parse(Request.Form["age-digit"]));
            fields.Add("СтажВождения", string.IsNullOrEmpty(Request.Form["experience-digit"]) ? 0 : Int32.Parse(Request.Form["experience-digit"]));
            var toClient = true;
            if (model.NewClientId != null)
            {
                clientsModel.UpdateClient(model.NewClientId, fields);
            }
            else
            {
                model.NewClientId = clientsModel.RegisterClient(CurrentUser.Id, fields).ToString();
                toClient = false;

            }
            var avatarUpload = Request.Files["avatarUpload"];
            if (avatarUpload != null)
            {
                if (avatarUpload.ContentLength > 0)
                {
                    clientsModel.SetAvatar(model.NewClientId, avatarUpload);
                }

            }
            return toClient ? RedirectToAction("Client", new { id = model.NewClientId }) : RedirectToAction("Index", new { page = 1 });
        }

        [HttpPost]
        public ActionResult DeleteClients(string query, string status, int? pagesize, int? page)
        {
            var clientsId = Request.Form["clientid"].Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
            clientsModel.DeleteClients(CurrentUser.Id, clientsId);
            return RedirectToAction("Index", new { query, status, page, pagesize });
        }

        [HttpPost]
        public string CalcAge(string datetime)
        {
            var serializer = new JavaScriptSerializer();
            DateTime date;
            if (DateTime.TryParse(datetime, CultureInfo.CreateSpecificCulture("ru-RU"), DateTimeStyles.None, out date))
            {
                var age = new Age { FullAge = Int32.Parse(date.GetFullAge()) };
                age.Additional = DateTimeExtention.GetAgeCase(age.FullAge);
                if (age.FullAge >= 0)
                {
                    var result = serializer.Serialize(age);
                    return result;
                }
            }
            return "error";
        }
        [HttpPost]
        public string CalcExperience(string datetime, int ageClient)
        {
            var serializer = new JavaScriptSerializer();
            DateTime date;
            if (DateTime.TryParse(datetime, CultureInfo.CreateSpecificCulture("ru-RU"), DateTimeStyles.None, out date))
            {
                var age = new Age();
                age.FullAge = Int32.Parse(date.GetFullAge());
                age.Additional = DateTimeExtention.GetAgeCase(age.FullAge);
                if (age.FullAge >= ageClient - 18 && (ageClient - 18) > 0)
                {
                    age.FullAge = ageClient - 18;
                    age.Additional = DateTimeExtention.GetAgeCase(age.FullAge);
                    var result = serializer.Serialize(age);
                    return result;
                }
                if (age.FullAge >= 0)
                {
                    var result = serializer.Serialize(age);
                    return result;
                }
            }
            return "error";
        }

        public ActionResult Client(string id)
        {
            var model = new MyClientViewModel();
            if (!string.IsNullOrEmpty(id))
            {
                model.Client = clientsModel.GetClient(id, CurrentUser.Id);
                return View(model);
            }
            if (Request.UrlReferrer != null) return Redirect(Request.UrlReferrer.AbsolutePath);
            return RedirectToAction("Index", "My");
        }

        [HttpPost]
        public string SaveNotes(string clientId, string notes)
        {
            try
            {
                userModel.SetValue(clientId, "Заметки", notes);
                return "ok";
            }
            catch (Exception)
            {
                return "Не удалось сохранить. Попробуйте еще раз.";
            }
        }
        [HttpPost]
        public ActionResult DeleteObjects(string query, string status, string pagesize, int? page)
        {
            var objectId = Request.Form["objectid"].Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
            clientsModel.DeleteObjects(CurrentUser.Id, objectId);
            return RedirectToAction("Objects", new { query, status, page, pagesize });
        }


        public ActionResult Trash(string pagesize, int? page, string query)
        {
            var model = new MyTrashViewModel();
            if (!page.HasValue)
            {
                page = 1;
            }
            if (string.IsNullOrEmpty(pagesize) || pagesize == "0")
            {
                pagesize = model.ListForPageSize.First().Value;
            }
            model.TrashItems.AddRange(clientsModel.GetDeleteClients(CurrentUser.Id, query));
            model.TrashItems.AddRange(clientsModel.GetDeleteObjects(CurrentUser.Id, query));
            model.TrashItems.AddRange(partnerModel.GetDeletePartners(query));
            model.TrashItems = model.TrashItems.OrderBy(x => x.Name).ToList();
            model.PageCount = (int)Math.Ceiling((double)model.TrashItems.Count / Int32.Parse(pagesize));
            model.PageNumber = page.Value;
            model.TrashItems =
                model.TrashItems.Skip((page.Value - 1) * Int32.Parse(pagesize)).Take(Int32.Parse(pagesize)).ToList();
            return View(model);
        }

        [HttpPost]
        public ActionResult DeleteOrRestoreTrashItems(string pagesize, int? page, string query, string[] itemsId, string action)
        {
            switch (action)
            {
                case "delete":
                    foreach (var id in itemsId)
                    {
                        rosModel.DeleteEntity(id);
                    }
                    break;
                case "restore":
                    foreach (var id in itemsId)
                    {
                        rosModel.UpdateEntityValue(id, "Удален", false);
                    }
                    break;
            }
            return RedirectToAction("Trash", new { page, pagesize, query });
        }

        [HttpGet]
        public ActionResult ClearTrash(string pagesize, int? page, string query)
        {
            clientsModel.ForeverDeleteObjectsAndClients(CurrentUser.Id);
            partnerModel.ForeverDeletePartners(CurrentUser.Id);
            return RedirectToAction("Trash", new { page, pagesize, query });
        }
        public ActionResult RestoreItem(string pagesize, int? page, string query, string restoreId)
        {
            if (!string.IsNullOrEmpty(restoreId))
            {
                rosModel.UpdateEntityValue(restoreId, "Удален", false);
            }
            return RedirectToAction("Trash", new { page, pagesize, query });
        }
        public ActionResult ForeverDeleteItem(string pagesize, int? page, string query, string deleteId)
        {
            if (!string.IsNullOrEmpty(deleteId))
            {
                rosModel.DeleteEntity(deleteId);
            }
            return RedirectToAction("Trash", new { page, pagesize, query });
        }
    }
}
